home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Ham Radio 2000 #2
/
Ham Radio 2000 - Volume 2.iso
/
HAMV2
/
TCP_IP
/
TNOS230S
/
NR4SUBR.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-12-23
|
5KB
|
240 lines
/*
* nr4subr.c: subroutines for net/rom transport layer.
* Copyright 1989 by Daniel M. Frank, W9NK. Permission granted for
* non-commercial distribution only.
*/
#include "global.h"
#ifdef NETROM
#include "mbuf.h"
#include "timer.h"
#include "ax25.h"
#include "netrom.h"
#if !defined(_lint)
static char rcsid[] OPTIONAL = "$Id: nr4subr.c,v 1.12 1996/12/23 20:37:36 root Exp root $";
#endif
/* Get a free circuit table entry, and allocate a circuit descriptor.
* Initialize control block circuit number and ID fields.
* Return a pointer to the circuit control block if successful,
* NULLNR4CB if not.
*/
struct nr4cb *
new_n4circ ()
{
int i;
struct nr4cb *cb;
for (i = 0; i < NR4MAXCIRC; i++) /* find a free circuit */
if (Nr4circuits[i].ccb == NULLNR4CB)
break;
if (i == NR4MAXCIRC) /* no more circuits */
return NULLNR4CB;
cb = Nr4circuits[i].ccb =
(struct nr4cb *) callocw (1, sizeof (struct nr4cb));
cb->mynum = (int16) i;
cb->myid = Nr4circuits[i].cid;
return cb;
}
/* Set the window size for a circuit and allocate the buffers for
* the transmit and receive windows. Set the control block window
* parameter. Return 0 if successful, -1 if not.
*/
int
init_nr4window (struct nr4cb *cb, unsigned window)
{
if (window == 0 || window > NR4MAXWIN) /* reject silly window sizes */
return -1;
cb->txbufs = (struct nr4txbuf *) callocw (window, sizeof (struct nr4txbuf));
cb->rxbufs = (struct nr4rxbuf *) callocw (window, sizeof (struct nr4rxbuf));
cb->window = window;
return 0;
}
/* Free a circuit. Deallocate the control block and buffers, and
* increment the circuit ID. No return value.
*/
void
free_n4circ (struct nr4cb *cb)
{
unsigned circ;
if (cb == NULLNR4CB)
return;
circ = cb->mynum;
if (cb->txbufs != (struct nr4txbuf *) 0)
free (cb->txbufs);
if (cb->rxbufs != (struct nr4rxbuf *) 0)
free (cb->rxbufs);
/* Better be safe than sorry: */
free_q (&cb->txq);
free_q (&cb->rxq);
free (cb);
if (circ > (unsigned) NR4MAXCIRC) /* Shouldn't happen. */
return;
Nr4circuits[circ].ccb = NULLNR4CB;
Nr4circuits[circ].cid++;
}
/* See if any open circuit matches the given parameters. This is used
* to prevent opening multiple circuits on a duplicate connect request.
* Returns the control block address if a match is found, or NULLNR4CB
* otherwise.
*/
struct nr4cb *
match_n4circ (theindex, id, user, node)
int theindex; /* index of remote circuit */
int id; /* id of remote circuit */
char *user; /* address of remote user */
char *node; /* address of originating node */
{
int i;
struct nr4cb *cb;
for (i = 0; i < NR4MAXCIRC; i++) {
if ((cb = Nr4circuits[i].ccb) == NULLNR4CB)
continue; /* not an open circuit */
if (cb->yournum == (unsigned) theindex && cb->yourid == (unsigned) id
&& addreq (cb->remote.user, user)
&& addreq (cb->remote.node, node))
return cb;
}
/* if we get to here, we didn't find a match */
return NULLNR4CB;
}
/* Validate the index and id of a local circuit, returning the control
* block if it is valid, or NULLNR4CB if it is not.
*/
struct nr4cb *
get_n4circ (theindex, id)
int theindex; /* local circuit index */
int id; /* local circuit id */
{
struct nr4cb *cb;
if (theindex >= NR4MAXCIRC)
return NULLNR4CB;
if ((cb = Nr4circuits[theindex].ccb) == NULLNR4CB)
return NULLNR4CB;
if (cb->myid == (unsigned) id)
return cb;
else
return NULLNR4CB;
}
/* Return 1 if b is "between" (modulo the size of an unsigned char)
* a and c, 0 otherwise.
*/
int
nr4between (a, b, c)
unsigned a, b, c;
{
if ((a <= b && b < c) || (c < a && a <= b) || (b < c && c < a))
return 1;
else
return 0;
}
/* Set up default timer values, etc., in newly connected control block.
*/
void
nr4defaults (struct nr4cb *cb)
{
int i;
struct timer *t;
if (cb == NULLNR4CB)
return;
/* Set up the ACK and CHOKE timers */
set_timer (&cb->tack, Nr4acktime);
cb->tack.func = nr4ackit;
cb->tack.arg = cb;
set_timer (&cb->tchoke, Nr4choketime);
cb->tchoke.func = nr4unchoke;
cb->tchoke.arg = cb;
cb->rxpastwin = uchar (cb->window);
/* Don't actually set the timers, since this is done */
/* in nr4sbuf */
for (i = 0; (unsigned) i < cb->window; i++) {
t = &cb->txbufs[i].tretry;
t->func = nr4txtimeout;
t->arg = cb;
}
}
/* See if this control block address is valid */
int
nr4valcb (struct nr4cb *cb)
{
int i;
if (cb == NULLNR4CB)
return 0;
for (i = 0; i < NR4MAXCIRC; i++)
if (Nr4circuits[i].ccb == cb)
return 1;
return 0;
}
#ifdef MSDOS
void
nr_garbage (int red)
{
int i;
struct nr4cb *ncp;
for (i = 0; i < NR4MAXCIRC; i++) {
ncp = Nr4circuits[i].ccb;
if (ncp != NULLNR4CB)
mbuf_crunch (&ncp->rxq);
}
}
#endif
#endif /* NETROM */